#include "rtp/RtpStreamRecv.h"

namespace Rtp {

    static constexpr uint64_t InactivityCheckInterval{ 1500u };        // In ms.
	static constexpr uint64_t InactivityCheckIntervalWithDtx{ 5000u }; // In ms.

    RtpStreamRecv::RtpStreamRecv(Rtp::RtpStreamRecv::Listener *listener,
        Rtp::RtpStream::Params& params, unsigned int sendNackDelayMs, bool useRtpInactivityCheck):RtpStream(listener, params, 10),
        sendNackDelaysMs(sendNackDelayMs), useRtpInactivityCheck(useRtpInactivityCheck), 
        transmissionCounter(params.spatialLayers, params.temporalLayers, this->params.useDtx ? 6000 : 2500), 
        mediaTransmissionCounter(true) {}

    RtpStreamRecv::~RtpStreamRecv() {
        delete this->inactivityCheckPeriodicTimer;
        this->inactivityCheckPeriodicTimer = nullptr;
    }

    bool RtpStreamRecv::ReceivePacket(Rtp::RtpPacket *packet) {
        if (!Rtp::RtpStream::ReceiveStreamPacket(packet)) { // 父类方法
            //"packet discarded"
            return false;
        }

        if (packet->GetPayloadType() == GetPayloadType()) { // payloadType一样

        }

        if (this->params.useNack) {
            if (HasRtx()) {
                this->nackGenerator->ReceivePacket(packet, false);
            } else if (this->nackGenerator->ReceivePacket(packet, false)) {
                RtpStream::PacketRetransmitted(packet);
                RtpStream::PacketRepaired(packet);
            }
        }

        CalculateJitter(packet->GetTimestamp());

        this->transmissionCounter.Update(packet);

        this->mediaTransmissionCounter.Update(packet);

        if (packet->GetPayloadLength() == 0) {
            return true;
        }

        if (this->inactive) {
            this->inactive = false;
            ResetScore(10, true);
        }

        if (this->inactivityCheckPeriodicTimer) {
            this->inactivityCheckPeriodicTimer->Restart();
        }

        return true;
    }

    void RtpStreamRecv::CalculateJitter(uint32_t rtpTimestamp) {
        if (GetClockRate() == 0) {
            return;
        }
        auto transit = static_cast<int>((DepLibUV::GetTimeMs() * GetClockRate() / 1000) - rtpTimestamp);
        int d = transit - this->transit;

        if (this->transit == 0) {
            this->transit = transit;
            return;
        }

        this->transit = transit;
        if (d < 0) {
            d = -d;
        }
        this->jitter += (1.0 / 16.0) * static_cast<float>(d) - this->jitter;
    }
}